package com.supermarket.manage.business.outstock.service;

import com.alibaba.fastjson.JSON;
import com.supermarket.manage.common.constant.RedisKeyConstant;
import com.supermarket.manage.common.constant.StockConstant;
import com.supermarket.manage.common.dto.CodeStatus;
import com.supermarket.manage.common.dto.PageBean;
import com.supermarket.manage.common.dto.ResponseResult;
import com.supermarket.manage.common.dto.stock.request.OutstockPageParams;
import com.supermarket.manage.common.dto.stock.response.OutProdDto;
import com.supermarket.manage.common.dto.stock.response.OutstockDto;
import com.supermarket.manage.common.pojo.Member;
import com.supermarket.manage.common.pojo.MyUser;
import com.supermarket.manage.common.pojo.Outstock;
import com.supermarket.manage.common.utils.BigDecimalUtil;
import com.supermarket.manage.common.utils.TimeUtil;
import com.supermarket.manage.provider.api.outstock.OutstockService;
import com.supermarket.manage.provider.api.ucenter.MemberManageService;
import com.supermarket.manage.provider.api.ucenter.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author Faxon
 * @version 1.0
 * @date 2020-03-16 18:00
 **/
@Service
public class OutstockBusinessService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Reference(version = "1.0.0")
    private UserService userService;

    @Reference(version = "1.0.0")
    private OutstockService outstockService;

    @Reference(version = "1.0.0")
    private MemberManageService memberManageService;

    /**
     * 条件分页查询出库单
     *
     * @param params
     * @return
     */
    public ResponseResult<PageBean<Outstock>> getOutStockPageList(OutstockPageParams params) {
        PageBean<Outstock> pageBean = outstockService.getOutstockPageList(params);
        if (pageBean == null) {
            return new ResponseResult<>(CodeStatus.FAIL, "查询失败");
        }
        //设置经办人
        List<MyUser> users = userService.getUserByBuyerId(params.getBuyerId());
        Set<String> memberIds = new HashSet<>();
        pageBean.getDataList().forEach(i -> {
            memberIds.add(i.getMemberId());
            users.forEach(u -> {
                if (i.getOperator().equals(u.getId())) {
                    i.setOperatorName(u.getUsername());
                }
            });
        });
        //设置会员手机号
        if (params.getType().equals(StockConstant.SALE) && memberIds.size() > 0) {
            List<Member> members = memberManageService.getMembersByIds(memberIds);
            pageBean.getDataList().forEach(i -> {
                members.forEach(member -> {
                    if (member.getMid().equals(i.getMemberId())) {
                        i.setMemberPhone(member.getMphone());
                    }
                });
            });
        }
        return new ResponseResult<>(CodeStatus.OK, "查询成功", pageBean);
    }

    /**
     * 根据id获取出库单详情
     *
     * @param id
     * @return
     */
    public ResponseResult<OutstockDto> getOutstockById(String id) {
        OutstockDto outstock = outstockService.getOutstockById(id);
        if (outstock == null) {
            return new ResponseResult<>(CodeStatus.FAIL, "单据不存在");
        }
        //设置经办人名称
        MyUser user = userService.getUserByUserId(outstock.getOperator());
        outstock.setOperatorName(user.getUsername());
        //设置会员手机号
        if (StringUtils.isNotBlank(outstock.getMemberId())) {
            Member member = memberManageService.getMemberById(outstock.getMemberId());
            if (member != null) {
                outstock.setMemberPhone(member.getMphone());
            }
        }
        //未完成的单据可编辑，将关联商品加入redis
        if (outstock.getStatus().equals(StockConstant.NOT_DONE)) {
            String key;
            if (outstock.getType().equals(StockConstant.SALE)) {
                key = RedisKeyConstant.SALE_OUT + outstock.getId();
            } else {
                key = RedisKeyConstant.BACK_OUT + outstock.getId();
            }
            redisTemplate.delete(key);
            List<OutProdDto> prodList = outstock.getOutProdDtos();
            Map<String, String> map = new HashMap<>(prodList.size());
            prodList.forEach(p -> {
                p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
                map.put(p.getPid(), JSON.toJSONString(p));
            });
            if (map.size() > 0) {
                redisTemplate.opsForHash().putAll(key, map);
            }
        }
        return new ResponseResult<>(CodeStatus.OK, "查询成功", outstock);
    }

    /**
     * 根据id完成出库单
     *
     * @param id
     * @return
     */
    public ResponseResult<Void> doneOutstockById(String id) {
        Outstock outstock = new Outstock();
        outstock.setId(id);
        outstock.setStatus(StockConstant.DONE);
        Boolean aBoolean = outstockService.doneOutstockById(outstock);
        if (aBoolean) {
            Outstock memberSale = outstockService.getMemberByOutStockId(id);
            if (memberSale != null && StringUtils.isNotBlank(memberSale.getMemberId())) {
                //添加会员积分
                memberManageService.addIntegral(memberSale.getMemberId(), memberSale.getActuallyPrice());
            }
            return new ResponseResult<>(CodeStatus.OK, "已成功出库");
        }
        return new ResponseResult<>(CodeStatus.FAIL, "出库失败");
    }

    /**
     * 根据id删除出库单
     *
     * @param id
     * @return
     */
    public ResponseResult<Void> deleteOutstockById(String id) {
        Boolean aBoolean = outstockService.deleteOutstockById(id);
        if (aBoolean) {
            return new ResponseResult<>(CodeStatus.OK, "删除成功");
        }
        return new ResponseResult<>(CodeStatus.FAIL, "删除失败");
    }

    /**
     * 保存出库单
     *
     * @param type
     * @param outstock
     * @return
     */
    public ResponseResult<Void> saveOutstock(Integer type, Outstock outstock) {
        outstock.setTotalPrice(BigDecimalUtil.formatTwoPoint(outstock.getTotalPrice()));
        outstock.setActuallyPrice(BigDecimalUtil.formatTwoPoint(outstock.getActuallyPrice()));
        outstock.setStatus(StockConstant.NOT_DONE);
        Boolean aBoolean;
        String redisKey;
        //新增单据
        if (StringUtils.isBlank(outstock.getId())) {
            outstock.setType(type);
            aBoolean = outstockService.addOutstock(outstock);
            if (type.equals(StockConstant.SALE)) {
                redisKey = RedisKeyConstant.SALE_OUT + outstock.getOperator();
            } else {
                redisKey = RedisKeyConstant.BACK_OUT + outstock.getOperator();
            }
        }
        //编辑单据
        else {
            Outstock newOutstock = new Outstock();
            newOutstock.setId(outstock.getId());
            newOutstock.setTotalPrice(outstock.getTotalPrice());
            newOutstock.setActuallyPrice(outstock.getActuallyPrice());
            newOutstock.setRemark(outstock.getRemark());
            newOutstock.setUpdated(new Date());
            newOutstock.setOutstockProds(outstock.getOutstockProds());
            aBoolean = outstockService.updateOutstock(newOutstock);
            if (type.equals(StockConstant.SALE)) {
                redisKey = RedisKeyConstant.SALE_OUT + outstock.getId();
            } else {
                redisKey = RedisKeyConstant.BACK_OUT + outstock.getId();
            }
        }
        if (aBoolean) {
            //清空对应购物车
            redisTemplate.delete(redisKey);
            return new ResponseResult<>(CodeStatus.OK, "保存成功");
        }
        return new ResponseResult<>(CodeStatus.FAIL, "保存失败");
    }

    /**
     * 完成出库单
     *
     * @param type
     * @param outstock
     * @return
     */
    public ResponseResult<Void> doneOutstock(Integer type, Outstock outstock) {
        outstock.setTotalPrice(BigDecimalUtil.formatTwoPoint(outstock.getTotalPrice()));
        outstock.setActuallyPrice(BigDecimalUtil.formatTwoPoint(outstock.getActuallyPrice()));
        outstock.setStatus(StockConstant.DONE);
        Boolean aBoolean;
        String redisKey;
        //新增单据
        if (StringUtils.isBlank(outstock.getId())) {
            outstock.setType(type);
            aBoolean = outstockService.addOutstockAndUpdateStockingNumber(outstock);
            if (type.equals(StockConstant.SALE)) {
                redisKey = RedisKeyConstant.SALE_OUT + outstock.getOperator();
            } else {
                redisKey = RedisKeyConstant.BACK_OUT + outstock.getOperator();
            }
        }
        //编辑单据
        else {
            Outstock newOutstock = new Outstock();
            newOutstock.setId(outstock.getId());
            newOutstock.setTotalPrice(outstock.getTotalPrice());
            newOutstock.setActuallyPrice(outstock.getActuallyPrice());
            newOutstock.setRemark(outstock.getRemark());
            newOutstock.setUpdated(new Date());
            newOutstock.setOutstockProds(outstock.getOutstockProds());
            aBoolean = outstockService.updateOutstockAndUpdateStockingNumber(newOutstock);
            if (type.equals(StockConstant.SALE)) {
                redisKey = RedisKeyConstant.SALE_OUT + outstock.getId();
            } else {
                redisKey = RedisKeyConstant.BACK_OUT + outstock.getId();
            }
        }
        if (aBoolean) {
            //清空对应购物车
            redisTemplate.delete(redisKey);
            //增加会员积分
            if (StringUtils.isNotBlank(outstock.getMemberId())) {
                memberManageService.addIntegral(outstock.getMemberId(),  outstock.getActuallyPrice());
            }
            return new ResponseResult<>(CodeStatus.OK, "出库成功");
        }
        return new ResponseResult<>(CodeStatus.FAIL, "出库失败");
    }

    /**
     * 获取出库单导出数据
     *
     * @param params
     * @return
     */
    public List<Map<String, Object>> getOutstockExportMap(OutstockPageParams params) {
        List<Outstock> outstocks = outstockService.getOutstockList(params);
        //设置经办人
        List<MyUser> users = userService.getUserByBuyerId(params.getBuyerId());
        Set<String> memberIds = new HashSet<>();
        outstocks.forEach(i -> {
            memberIds.add(i.getMemberId());
            users.forEach(u -> {
                if (i.getOperator().equals(u.getId())) {
                    i.setOperatorName(u.getUsername());
                }
            });
        });
        //设置会员手机号
        if (params.getType().equals(StockConstant.SALE) && memberIds.size() > 0) {
            List<Member> members = memberManageService.getMembersByIds(memberIds);
            outstocks.forEach(i -> {
                members.forEach(member -> {
                    if (member.getMid().equals(i.getMemberId())) {
                        i.setMemberPhone(member.getMphone());
                    }
                });
            });
        }
        List<Map<String, Object>> result = new ArrayList<>();
        outstocks.forEach(outstock -> {
            Map<String, Object> map = new HashMap<>(8);
            map.put("id", outstock.getId());
            map.put("operator", outstock.getOperatorName());
            if (params.getType().equals(StockConstant.SALE)) {
                map.put("mPhone", outstock.getMemberPhone());
            }
            map.put("totalPrice", outstock.getTotalPrice());
            map.put("actuallyPrice", outstock.getActuallyPrice());
            map.put("remark", outstock.getRemark());
            if (outstock.getStatus().equals(StockConstant.DONE)) {
                map.put("status", "已完成");
            } else {
                map.put("status", "未完成");
            }
            map.put("updated", TimeUtil.formatDate(outstock.getUpdated(), TimeUtil.TIME_FORMAT));
            result.add(map);
        });
        return result;
    }
}
